package com.shundr.shipper.cargo.dao;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.UpdateBuilder;
import com.j256.ormlite.stmt.Where;
import com.shundr.shipper.cargo.model.CargoInfo;
import com.shundr.shipper.frame.constant.LContext;
import com.shundr.shipper.frame.db.LDaoManager;
import com.shundr.shipper.frame.util.LLogger;
/**
 * cargoDaoO
 * CargoDao
 * 
 * @author larry 2015-4-10 下午3:02:24 
 * @version 1.0.0
 *
 */
public class CargoDao {
	
	private Dao<CargoInfo, Integer> cargoDao;
	
	public CargoDao() {
		cargoDao = LDaoManager.createDao(CargoInfo.class);
	}
	
	/**
	 * 
	 * insert(这里用一句话描述这个方法的作用) 插入货源
	 * (这里描述这个方法适用条件 – 可选)
	 * @param cargoInfo void
	 * @exception
	 * @since  1.0.0
	 */
	public void insert(CargoInfo cargoInfo){
		try {
			cargoDao.create(cargoInfo);
		} catch (SQLException e) {
			LLogger.e("创建数据类型时异常" + e);
		}
	}
	
	/**
	 * 删除货源
	 * delete(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * @param info void
	 * @exception
	 * @since  1.0.0
	 */
	public void delete(final CargoInfo info){
		try {
			DeleteBuilder<CargoInfo, Integer> deleteBuilder = cargoDao.deleteBuilder();
			deleteBuilder.where().eq("userId", info.getUserId());
			deleteBuilder.delete();
		} catch (SQLException e) {
			LLogger.e("删除货源时发生异常 ： " + e);
		}
	}
	
	/**
	 * 获取所有常跑路线货源
	 * getAll(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * @return
	 * List<CargoInfo>
	 * @exception
	 * @since  1.0.0
	 */
	public List<CargoInfo> getAll(){
		try {
			return cargoDao.queryForAll();
		} catch (SQLException e) {
			LLogger.e("查询所有货源时发生异常 ： " + e);
		}
		return new ArrayList<CargoInfo>();
	}
	
	/**
	 * 清空接收货源
	 * clear(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	public void clear(){
		try {
			cargoDao.deleteBuilder().delete();
		} catch (SQLException e) {
			LLogger.e("查询所有货源时发生异常 ： " + e);
		}
	}
	
	/**
	 * 获取未读货源数量
	 * getNoReadCount(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * @return
	 * int
	 * @exception
	 * @since  1.0.0
	 */
	public int getNoReadCount(){
		try {
			QueryBuilder<CargoInfo, Integer> queryBuilder = cargoDao.queryBuilder();
			queryBuilder.where().eq("localType", CargoInfo.CargoLocalType.unread).and().eq("localUserId", LContext.USER_ID);
			return queryBuilder.query().size();
		} catch (SQLException e) {
			LLogger.e("查询货源未读时发生异常 ： " + e);
		}
		return 0;
	}
	
	/**
	 * 获取第一条数据
	 * getFirst(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * @return
	 * CargoInfo
	 * @exception
	 * @since  1.0.0
	 */
	public CargoInfo getFirst(){
		try {
			QueryBuilder<CargoInfo, Integer> queryBuilder = cargoDao.queryBuilder();
			queryBuilder.where().eq("localType", CargoInfo.CargoLocalType.unread).and().eq("localUserId", LContext.USER_ID);
			List<CargoInfo> list = queryBuilder.query();
			if(list.size() > 0){
				return list.get(list.size() - 1);
			}
		} catch (SQLException e) {
			LLogger.e("查询货源未读时发生异常 ： " + e);
		}
		return null;
	}
	
	/**
	 * 将未读标记为已读
	 * updateUnRead(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * @param info
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	public void updateUnRead(CargoInfo info) {
		try {
			UpdateBuilder<CargoInfo, Integer> updateBuilder = cargoDao.updateBuilder();
			updateBuilder.where().eq("localUserId", LContext.USER_ID).and()
					.eq("cargoId", info.getCargoId());
			updateBuilder.updateColumnValue("localType", CargoInfo.CargoLocalType.history);
			updateBuilder.update();
		} catch (SQLException e) {
			LLogger.e("更新货源未读时发生异常 ： " + e);
		}
	}
	
	/**
	 * 删除指定路线内的货源
	 * deleteCargoByRoute(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * @param srcCode
	 * @param destCode
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	public void deleteCargoByRoute(int srcCode,int destCode){
		List<CargoInfo> list = getCargoListByRoute(srcCode, destCode);
		try {
			cargoDao.delete(list);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * getCargoListByRoute(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * @param srcCode
	 * @param destCode
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	public List<CargoInfo> getCargoListByRoute(int srcCode,int destCode){
		List<CargoInfo> list = new ArrayList<CargoInfo>();
		if(srcCode == 0 && destCode == 0){
			try {
				QueryBuilder<CargoInfo, Integer> queryBuilder = cargoDao.queryBuilder();
				queryBuilder.where().eq("localUserId", LContext.USER_ID);
				queryBuilder.orderBy("cargoInsertTime", false);
				LLogger.e("larry",queryBuilder.prepareStatementString());
				list.addAll(queryBuilder.query());
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}else{
			int maxSrcCode;
			if (srcCode % 10000 == 0) {
				maxSrcCode = srcCode + 10000;
			} else if (srcCode % 100 == 0) {
				maxSrcCode = srcCode + 100;
			} else {
				maxSrcCode = srcCode + 1;
			}
			int maxDestCode;
			if (destCode % 10000 == 0) {
				maxDestCode = destCode + 10000;
			} else if (destCode % 100 == 0) {
				maxDestCode = destCode + 100;
			} else {
				maxDestCode = destCode + 1;
			}
			
//			String sql="select count(*) from "+tableName+" where cargoDstCode>="+destCode+
//					" and cargoDstCode<"+maxDestCode+" and cargoSrcCode>="+srcCode+" and cargoSrcCode<"
//					+maxSrcCode+" and localUserId="+localUserId+" and localType="+CargoLocalType.unread;
			try {
				QueryBuilder<CargoInfo, Integer> queryBuilder = cargoDao.queryBuilder();
				Where<CargoInfo, Integer> where = queryBuilder.where();
				where.ge("cargoDstCode", destCode);
				where.lt("cargoDstCode", maxDestCode);
				where.ge("cargoSrcCode", srcCode);
				where.lt("cargoSrcCode", maxSrcCode);
				where.eq("localUserId", LContext.USER_ID);
				where.and(5);
				queryBuilder.orderBy("cargoInsertTime", false);
				LLogger.e("larry",queryBuilder.prepareStatementString());
				list.addAll(queryBuilder.query());
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return list;
		
	}
	
	/**
	 * 分页获取推荐货源
	 * @param srcCode
	 * @param destCode
	 * @param pageIndex
	 * @param pageSize
	 * @return
	 */
	public List<CargoInfo> getCargoListByRoute(int srcCode,int destCode,int pageIndex,int pageSize){
		List<CargoInfo> list = new ArrayList<CargoInfo>();
		if(srcCode == 0 && destCode == 0){
			try {
				QueryBuilder<CargoInfo, Integer> queryBuilder = cargoDao.queryBuilder();
				queryBuilder.where().eq("localUserId", LContext.USER_ID);
				queryBuilder.limit(pageSize).offset(pageIndex);
				queryBuilder.orderBy("cargoInsertTime", false);
				LLogger.e("larry",queryBuilder.prepareStatementString());
				list.addAll(queryBuilder.query());
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}else{
			int maxSrcCode;
			if (srcCode % 10000 == 0) {
				maxSrcCode = srcCode + 10000;
			} else if (srcCode % 100 == 0) {
				maxSrcCode = srcCode + 100;
			} else {
				maxSrcCode = srcCode + 1;
			}
			int maxDestCode;
			if (destCode % 10000 == 0) {
				maxDestCode = destCode + 10000;
			} else if (destCode % 100 == 0) {
				maxDestCode = destCode + 100;
			} else {
				maxDestCode = destCode + 1;
			}
			
//			String sql="select count(*) from "+tableName+" where cargoDstCode>="+destCode+
//					" and cargoDstCode<"+maxDestCode+" and cargoSrcCode>="+srcCode+" and cargoSrcCode<"
//					+maxSrcCode+" and localUserId="+localUserId+" and localType="+CargoLocalType.unread;
			try {
				QueryBuilder<CargoInfo, Integer> queryBuilder = cargoDao.queryBuilder();
				Where<CargoInfo, Integer> where = queryBuilder.where();
				where.ge("cargoDstCode", destCode);
				where.lt("cargoDstCode", maxDestCode);
				where.ge("cargoSrcCode", srcCode);
				where.lt("cargoSrcCode", maxSrcCode);
				where.eq("localUserId", LContext.USER_ID);
				where.and(5);
				queryBuilder.limit(pageSize).offset(pageIndex);
				queryBuilder.orderBy("cargoInsertTime", false);
				LLogger.e("larry",queryBuilder.prepareStatementString());
				list.addAll(queryBuilder.query());
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return list;
		
	}
	
	/**
	 * 批量插入货源
	 * @param infos
	 */
	public void syncData(final List<CargoInfo> infos) {
		if(infos == null || infos.size() == 0)
			return;
		try {
			cargoDao.callBatchTasks(new Callable<Void>() {

				@Override
				public Void call() throws Exception {
//					userDao.deleteBuilder().delete();
					for(CargoInfo info : infos) {
						cargoDao.create(info);
					}
					return null;
				}});
		} catch (Exception e) {
			LLogger.e("保存数据类型时发生异常 ： " + e);
		}
	}

}
